#include "server.h"
using namespace std;

bool InitSocket() {
	WSAData wsaData;
	if(WSAStartup(MAKEWORD(2,2), &wsaData)) {
		cout<<WSAGetLastError()<<endl;
		return false;
	}
	return true;
}
string NormalPath(string path) {
	vector<string> v;
	string d="";
	int i=path.find_first_of("/\\"),p=0;
	bool rel=false;
	if(i<0) return path;
	else if(i) {
		if(path[i-1]==':') d.assign(path,0,2);
		else {rel=true;i=-1;}
	}
	for(int j=i+1,n;;j=i+1) {
		i=path.find_first_of("/\\",j);
		n=i<0?i:i-j;
		string s(path,j,n);
		if(!s.compare("."));
		else if(!s.compare("..")) {
			if(v.size()) v.pop_back();
			else if(rel) p++;
		} else if(i<0||!s.empty()) v.push_back(s);
		if(i<0) break;
	}
	if(v.size()||p) {
		if(p) {
			d.assign("..");
			for(i=1;i<p;i++) {
				d.push_back('/');
				d.append("..");
			}
			rel=false;
		}
		for(vector<string>::iterator vi=v.begin();vi!=v.end();vi++) {
			if(rel) rel=false;
			else d.push_back('/');
			d.append(*vi);
		}
	} else if(rel) d.push_back('.');
	else d.push_back('/');
	return d;
}
Address::Address() {	// no initiation
	ZeroMemory(&addrex,sizeof(addrex));
}
Address::Address(string addr) {
	FromHost(addr);
}
Address::Address(string host,int port) {
	FromHost(host,port);
}
Address::Address(sockaddr *addr) {
	FromSockAddr(addr);
}
Address::Address(Address *addr) {
	host=addr->host;
	port=addr->port;
	addrex=addr->addrex;
}
string Address::ToString() {
	char buf[46];
	DWORD l=46,s;
	s=GetType()==AF_INET?sizeof(sockaddr_in):sizeof(sockaddr_in6);
	if(WSAAddressToString(&addrex.addr,s,NULL,buf,&l)) return "(null)";
	return string(buf);
}
sockaddr Address::SockAddress() {
	return addrex.addr;
}
int Address::GetType() {
	return addrex.addr.sa_family;
}
bool Address::FromHost(string host,int port) {
	if(!host.empty()) {
		// support ip:port, param PORT as default port
		int o=host.find(':');
		if(o>=0) port=atoi(host.substr(o+1).c_str());
		host=host.substr(0,o);
		if(host.empty()) host.assign("0.0.0.0");

		this->host=host;
		addrinfo *ai;
		if(getaddrinfo(host.c_str(),NULL,NULL,&ai)) {
			cout<<"Parse failed: "<<host<<endl;
			return false;
		}
		for(; ai; ai=ai->ai_next) {
			switch(ai->ai_family) {
			case AF_INET:
				addrex.addrv4=*(sockaddr_in *)ai->ai_addr;
				break;
			case AF_INET6:
				addrex.addrv6=*(sockaddr_in6 *)ai->ai_addr;
				break;
			default:
				continue;
			}
			break;
		}
		if(!ai) {
			cout<<"IP not found: "<<host<<endl;
			return false;
		}
	}
	switch(GetType()) {
	case AF_INET:
		addrex.addrv4.sin_port=htons(port);
		break;
	case AF_INET6:
		addrex.addrv6.sin6_port=htons(port);
		break;
	default:
		cout<<"Invalid IP type."<<endl;
		return false;
	}
	this->port=port;
	return true;
}
bool Address::FromHost(string addr) {
	return FromHost(addr,port);
}
bool Address::FromHost() {
	return FromHost("",port);
}
bool Address::FromSockAddr(sockaddr *addr) {
	if(addr) {
		addrex.addr=*addr;
		string buf=ToString();
		int o=buf.find(':');
		host=buf.substr(0,o);
	}
	switch(GetType()) {
	case AF_INET:
		port=ntohs(addrex.addrv4.sin_port);
		break;
	case AF_INET6:
		port=ntohs(addrex.addrv6.sin6_port);
		break;
	default:
		return false;
	}
	return true;
}
bool Address::FromSockAddr() {
	return FromSockAddr(NULL);
}

Server::Server() {
	addr=NULL;
}
void Server::SetAddress(Address *a) {
	if(!addr) addr=a;
}
bool Server::Bind() {
	if(!addr) return false;
	sock=WSASocket(AF_INET,SOCK_STREAM,0,NULL,0,WSA_FLAG_OVERLAPPED);
	sockaddr a=addr->SockAddress();
	if(bind(sock,&a,sizeof(sockaddr))<0) {
		cout<<"Bind error."<<endl
			<<WSAGetLastError()<<endl;
		return false;
	}
	if(listen(sock,5)) {
		cout<<"Listen error."<<endl
			<<WSAGetLastError()<<endl;
		return false;
	}
	status++;
	return true;
}
void Server::StartServer() {}
